home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
L' Effet Pommier 3
/
L'Effet Pommier - Volume 03.iso
/
Programmation
/
gray image 2.1
/
read_pgm.cc
< prev
next >
Wrap
Text File
|
1995-05-30
|
5KB
|
157 lines
// This may look like C code, but it is really -*- C++ -*-
/*
************************************************************************
*
* Grayscale Image
*
* Read an image from a Portable GrayMap (pgm) file
*
* The program reads a "binary" (RAWBITS) pgm file of the following format
* - A "magic number" for identifying the file type. A pgm
* file's RAWBITS magic number is the two characters "P5".
* - Whitespace (blanks, TABs, CRs, LFs).
* - A width, formatted as ASCII characters in decimal.
* - Whitespace.
* - A height, again in ASCII decimal.
* - Whitespace.
* - The maximum gray value, again in ASCII decimal. For RAWBITS pgm file
* the maximum grayscale value cannot exceed 255.
* - A _single_ character of whitespace (typically a newline).
* - Width * height gray values, each as plain bytes, between
* 0 and the specified maximum value, stored consecutivly,
* starting at the top-left corner of the graymap, proceding in normal
* English reading order.
* A value of 0 means black, and the maximum value means white.
*
* For more detail, see documentation on PBMPLUS package (specifically,
* pgm(5)).
*
* $Id: read_pgm.cc,v 2.0 1995/03/06 20:57:48 oleg Exp oleg $
*
************************************************************************
*/
#include "image.h"
#include "endian_io.h"
#include <iostream.h>
#include <ctype.h>
/*
*------------------------------------------------------------------------
* Class PGMFile
* designed to contain the control info about the image
* as defined in the Portable GrayMap file
*/
class PGMFile : public PixelPrimAction
{
EndianIn& inf; // stream to read from
card pixmap_width; // Dimensions of the graymap
card pixmap_height;
card max_gray_value; // Maximum value of a graymap pixel
card pixmap_depth; // ceil(log2(max_gray_value))
void operation(GRAY& pixel);
public:
PGMFile(EndianIn& _inf);
void info(void) const; // Dump the header information
const char * q_name(void) const { return ""; }
card q_nrows(void) const { return pixmap_height; }
card q_ncols(void) const { return pixmap_width; }
card q_depth(void) const { return pixmap_depth; }
};
/*
*------------------------------------------------------------------------
* Construct the PGMFile
* by reading the header of a PGM file
*/
PGMFile::PGMFile(EndianIn& file) : inf(file)
{
const char * magic_str = "P5";
char read_magic_str[3];
read_magic_str[0] = inf.read_byte("Reading magic string");
read_magic_str[1] = inf.read_byte("Reading magic string");
read_magic_str[2] = '\0';
if( strcmp(read_magic_str,magic_str) != 0 )
_error("Read magic string '%s' is not what's expected '%s':"
"it's not a Portable GrayMap (PGM) file",read_magic_str,magic_str);
if( !(inf >> pixmap_width) )
_error("Failed to read the number of columns (graymap width)");
if( !(inf >> pixmap_height) )
_error("Failed to read the number of rows (graymap height)");
if( !(inf >> max_gray_value) )
_error("Failed to read the maximum gray value in the map");
char c;
assert( inf.get(c) );
assure( isspace(c), "Failed to get a single space after the header");
assert( pixmap_width > 0 && pixmap_height > 0 && max_gray_value > 0);
if( max_gray_value > 255 )
_error("Can't handle the graymap with the maximum gray value, %d, "
"greater than 255",max_gray_value);
{
int t;
for(pixmap_depth=0,t=1; t < max_gray_value+1; pixmap_depth++, t *= 2)
;
}
}
/*
*------------------------------------------------------------------------
* Print out all the control information pertaining to the
* X Window Image read
*/
void PGMFile::info(void) const
{
cout << "\n\n=====>The following Portable GrayMap has been read";
cout << "\nPixmap depth: " << pixmap_depth;
cout << "\nPixmap width: " << pixmap_width;
cout << "\nPixmap height: " << pixmap_height;
cout << "\nMax gray value: " << max_gray_value;
cout << "\n-----End of PGM information\n";
}
/*
*------------------------------------------------------------------------
* Read a pixelmap
*/
void PGMFile::operation(GRAY& pixel)
{
pixel = inf.read_byte("reading the pixel matrix");
}
/*
*========================================================================
* Root module - actual IMAGE constructor
*/
void IMAGE::read_pgm(EndianIn& file, const bool print_header_info)
{
message("Reading the Portable GrayMap (PGM)\n");
PGMFile pgmfile(file);
if( print_header_info )
pgmfile.info();
allocate(pgmfile.q_nrows(),pgmfile.q_ncols(),pgmfile.q_depth());
apply(pgmfile);
cout << "\n" << ncols << "x" << nrows << "x" << bits_per_pixel << " image '"
<< name << "' has been read" << endl;
}